﻿using System;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;

using PlanningGIS.Util.Convertor;
using PlanningGIS.ArcGIS;
using PlanningGIS.Util.Log;
using PlanningGIS.Engine.Controls;

namespace PlanningGIS.DataCheck.model
{
  
    public class ContourEleConsistencyCheck : Check
    {
        /// <summary>
        /// 等高线高程一致性检查
        /// </summary>
        /// <param name="errType">错误类型</param>
        /// <param name="pFeatLyr">等高线图层</param>
        /// <param name="eleFieldName">高程字段名称</param>
        /// <param name="extent">检查范围</param>
        /// <param name="tol">搜索容差</param>
        /// <param name="whereClause">属性过滤条件</param>
        /// <returns></returns>
        public int Check(string errType,IFeatureLayer pFeatLyr,string eleFieldName, IGeometry extent,double buffer,string fcodeFieldName,string whereClause)
        {
            IFeatureClass pFeatCls = pFeatLyr.FeatureClass;
            if (pFeatCls.ShapeType != esriGeometryType.esriGeometryPolyline)
            {
                
                    LogHelper.WriteLog("[" + pFeatLyr.Name + "]图层不是线层，检查失败！");
                return 0;
            }

            int indexEle = pFeatCls.FindField(eleFieldName);
            if (indexEle == -1)
            {
                
                    LogHelper.WriteLog("[" + pFeatLyr.Name + "]图层高程属性["+ eleFieldName +"]不存在或设置有误，检查失败！");
                return 0;
            }

            int indexFcode = pFeatCls.FindField(fcodeFieldName);
            if (indexFcode == -1)
            {
                
                    LogHelper.WriteLog("[" + pFeatLyr.Name + "]图层分类代码属性[" + fcodeFieldName + "]不存在或设置有误，会有误查情况发生！");
            }


            IFeatureSelection pFeatSel = (IFeatureSelection)pFeatLyr;

            ISelectionSet pSelset;
            IEnumIDs pIDs;

            //记录错误图形
            IGeometryCollection pGeomCln = (IGeometryCollection)new GeometryBag();
            IRelationalOperator pRelation = (IRelationalOperator)pGeomCln;

            int errCount = 0;
            int count = 0;

            string sql = eleFieldName + " is not null"; //找到所有“高程”属性不为空的要素进行检查

            if (whereClause != null&&whereClause.Trim()!="")
            {
                sql = sql + " and (" + whereClause + ")";
            }

            if (showFakePro != null) showFakePro(true);
            
                LogHelper.WriteLog("开始形成选择集。。。");
            pSelset = CursorHelper.GetSelset(pFeatSel, extent, sql, esriSpatialRelEnum.esriSpatialRelIntersects);
            
                LogHelper.WriteLog("形成选择集完毕。共有" + pSelset.Count + "个要素参与检查。");

            if (showFakePro != null) showFakePro(false);
            if (pSelset.Count == 0) return 0;

            if (setProcessBarMax != null) setProcessBarMax(pSelset.Count);

            pIDs = pSelset.IDs;
            long lID;

            while ((lID = pIDs.Next()) != -1)
            {
                if (IsStop()) break;

                count++;
                if (setProcessBarCurrent != null) setProcessBarCurrent(count);

                IFeature pFeature = pFeatCls.GetFeature((int)lID);
                IPolyline pPolyline = (IPolyline)pFeature.ShapeCopy;

                if (pPolyline == null || pPolyline.IsEmpty) continue;

                IPoint pPoint;
                IGeometry pBuffer;
                IRelationalOperator pRelationalOperation;

                //string whereClause;
                //whereClause =(pFeatCls  as IClass).OIDFieldName + " <> " + lID;

                IFeatureCursor pFeatCur;
                IFeature pFeature2;

                pPoint = pPolyline.FromPoint;
                pBuffer = GeometryHelper.GetBuffer(pPoint, buffer, (pFeatCls as IGeoDataset).SpatialReference);
                pRelationalOperation = pBuffer as IRelationalOperator;
                pFeatCur = CursorHelper.GetCursor(pFeatLyr, pBuffer, (pFeatCls as IClass).OIDFieldName + " <> " + lID);//whereClause);
                while ((pFeature2 = pFeatCur.NextFeature()) != null)
                {
                    if (StopAnyWay) break;

                    //分类代码不一致的，直接跳过（？）
                    if (indexFcode != -1 && StringHelper.ConvertWRTNull(pFeature.get_Value(indexFcode)) !=
                        StringHelper.ConvertWRTNull(pFeature2.get_Value(indexFcode))) continue;

                    IPolyline pPolyline2 = pFeature2.ShapeCopy as IPolyline;
                    IPoint pFromPoint = pPolyline2.FromPoint;
                    IPoint pToPoint = pPolyline2.ToPoint;

                    if (pRelationalOperation.Equals(pFromPoint) || pRelationalOperation.Contains(pFromPoint) ||
                        pRelationalOperation.Equals(pToPoint) || pRelationalOperation.Contains(pToPoint))
                    {
                        if (pFeature2.get_Value(indexEle) != DBNull.Value && Math.Abs(Convert.ToDouble(pFeature.get_Value(indexEle)) - Convert.ToDouble(pFeature2.get_Value(indexEle))) > 0.000001)
                        {
                            if (pRelation.Contains(pPoint) == false)
                            {
                                RecordListHelper.AddRecordItem(errType, pFeatLyr, null, pFeature, pFeature2, pPoint, "");
                                pGeomCln.AddGeometry(pPoint, ref Missing, ref  Missing);
                            }
                        }
                    }
                    DataCheckUtility.ReleaseComObject(pFromPoint);
                    DataCheckUtility.ReleaseComObject(pToPoint);
                    DataCheckUtility.ReleaseComObject(pPolyline2);
                }
                DataCheckUtility.ReleaseComObject(pBuffer);
                DataCheckUtility.ReleaseComObject(pFeatCur);

                pPoint = pPolyline.ToPoint;
                pBuffer = GeometryHelper.GetBuffer(pPoint, buffer, (pFeatCls as IGeoDataset).SpatialReference);
                pRelationalOperation = pBuffer as IRelationalOperator;
                pFeatCur = CursorHelper.GetCursor(pFeatCls, pBuffer, (pFeatCls as IClass).OIDFieldName + " <> " + lID);//whereClause);
                while ((pFeature2 = pFeatCur.NextFeature()) != null)
                {
                    if (StopAnyWay) break;

                    //分类代码不一致的，直接跳过（？）
                    if (indexFcode != -1 && StringHelper.ConvertWRTNull(pFeature.get_Value(indexFcode)) !=
                        StringHelper.ConvertWRTNull(pFeature2.get_Value(indexFcode))) continue;

                    IPolyline pPolyline2 = pFeature2.ShapeCopy as IPolyline;

                    IPoint pFromPoint = pPolyline2.FromPoint;
                    IPoint pToPoint = pPolyline2.ToPoint;

                    if (pRelationalOperation.Equals(pFromPoint) || pRelationalOperation.Contains(pFromPoint) ||
                        pRelationalOperation.Equals(pToPoint) || pRelationalOperation.Contains(pToPoint))
                    {
                        if (pFeature2.get_Value(indexEle) != DBNull.Value && Math.Abs(Convert.ToDouble(pFeature.get_Value(indexEle)) - Convert.ToDouble(pFeature2.get_Value(indexEle))) > 0.000001)
                        {
                            if (pRelation.Contains(pPoint) == false)
                            {
                                RecordListHelper.AddRecordItem(errType, pFeatLyr, null, pFeature, pFeature2, pPoint, "");
                                pGeomCln.AddGeometry(pPoint, ref Missing, ref  Missing);
                            }
                        }
                    }
                    DataCheckUtility.ReleaseComObject(pFromPoint);
                    DataCheckUtility.ReleaseComObject(pToPoint);
                    DataCheckUtility.ReleaseComObject(pPolyline2);
                }
                DataCheckUtility.ReleaseComObject(pBuffer);
                DataCheckUtility.ReleaseComObject(pFeatCur);

                DataCheckUtility.ReleaseComObject(pPolyline);
            }

            pFeatSel.Clear();

            if (finishPro != null) finishPro();
            errCount = pGeomCln.GeometryCount;
            DataCheckUtility.ReleaseComObject(pGeomCln);

            
                LogHelper.WriteLog("等高线高程一致性结束。共发现" + errCount + "处错误！\n");

            return errCount;
        }
    }
}
